/*
 * Copyright (c) 2010, Nikolaus Moll
 * All rights reserved.
 */
package net.miblounge.gradecalculator.core;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.miblounge.gradecalculator.core.descriptors.StudyRegulationsDescription;
import net.miblounge.gradecalculator.core.descriptors.University;

public abstract class AbstractDataProvider {
	private static AbstractDataProvider instance = null; 
	
	public class CourseOfStudiesInformation
	{
		private volatile int hashCode = 0;
		private final String university;
		private final String name;
		private final String degree;
		private List<String> availableSemesters;	// available regulations
		
		public CourseOfStudiesInformation(final String university, final String degree, final String name)
		{
			this.university = university;
			this.degree = degree;
			this.name = name;
			availableSemesters = new ArrayList<String>();
		}
		
		public String getUniversity() {
			return university;
		}

		public String getName() {
			return name;
		}
		
		public String getDegree() {
			return degree;
		}
		
		public List<String> getSemesters() {
			return availableSemesters;
		}
		
		public void addSemester(final String semester)
		{
			availableSemesters.add(semester);
		}

		public void addSemesters(final Collection<String> semesters)
		{
			availableSemesters.addAll(semesters);
		}

		@Override
		public int hashCode() {
			int result = hashCode;
			if (result == 0) {
				result = 17;
				result = 31 * result + university.hashCode();
				result = 31 * result + name.hashCode();
				result = 31 * result + degree.hashCode();
				hashCode = result;
			}
			
			return result;
		}

		@Override
		public boolean equals(final Object o) {
			if (o == this) {
				return true;
			}
			
			if (!(o instanceof CourseOfStudiesInformation)) {
				return false;
			}
			
			final CourseOfStudiesInformation c = (CourseOfStudiesInformation)o;
			
			return (university.equals(c.university) &&
					name.equals(c.name) &&
					degree.equals(c.degree));
		}
	}

	protected AbstractDataProvider()
	{
		if (instance != null) {
			throw new IllegalStateException();
		}
		instance = this;
	}

	public static AbstractDataProvider getInstance()
	{
		return instance;
	}

	public abstract University getUniversity(String name);
	public abstract StudyRegulationsDescription getSPODescription(String name);

	public abstract List<String> getUniversities();
	public abstract List<String> getDegrees(String university);
	public abstract List<String> getCourses(String university, String degree);
	public abstract List<String> getSemesters(String university, String degree, String course);

	//public abstract List<CourseOfStudiesInformation> getCourseOfStudiesByUniversity(String university);
}
